/*
 * AmplScriptWriter.cpp
 *
 *  Created on: 27 Jun 2011
 *      Author: s0965328
 */

#include "AmplScriptWriter.h"
#include "global_util_functions.h"
#include "GlobalVariables.h"
#include <algorithm>
#include <iostream>
#include <fstream>

using namespace std;

AmplScriptWriter::AmplScriptWriter(string model) {
	this->scriptList = new vector<AmplScript*>();
	this->modelname = model;
	this->script_num = 0;
	this->setUpRootScript();
}

void AmplScriptWriter::setUpRootScript()
{
	LOG_PAR("Setting up root script ");
	AmplScript* newScript = new AmplScript(this->modelname,0,this->script_num); //root has index = 0 script_num = 0;
	this->scriptList->push_back(newScript);
	this->script_num++;
}

void AmplScriptWriter::split()
{
	LOG_PAR("Before Splits - Num of Scripts File is ["<<this->scriptList->size()<<"]");
	vector<AmplScript*>::iterator scripts_iter;
	vector<AmplScript*> created;
	for(scripts_iter = this->scriptList->begin();scripts_iter!=this->scriptList->end();scripts_iter++)
	{
		AmplScript* script = *scripts_iter;
		script->index = 0;
		for(int i=1;i<GlobalVariables::degreeParallel;i++) //index start from 1. 0 index is the covered by root
		{
			AmplScript *newScript = new AmplScript(this->modelname,i,this->script_num);
			newScript->copyFrom(script);
			created.push_back(newScript);
			this->script_num++;
		}
	}
	for(scripts_iter = created.begin();scripts_iter!=created.end();scripts_iter++)
	{
		this->scriptList->push_back(*scripts_iter);
	}
	LOG_PAR("After Splits - Num of Scripts File is ["<<this->scriptList->size()<<"]");
}

//replace line : set SET_SUB_ARCS := {i in ARCS: ord(i)>n/2*%INDEX% and ord(i)<=n/2*%INDEX+1%};
//		    to : set SET_SUB_ARCS := {i in ARCS: ord(i)>n/2*AmplScript::index and ord(i)<=n/2*(AmplScript::index+1)};
void AmplScriptWriter::writeParallelPartOfScript(string line)
{
	LOG_PAR("writeParallelPartOfScript ["+line+"]");
	vector<AmplScript*>::iterator scripts_iter;
	ostringstream oss;
	for(scripts_iter = this->scriptList->begin();scripts_iter!=this->scriptList->end();scripts_iter++)
	{
		string line_copy = line;
		AmplScript *script = *scripts_iter;
		LOG_PAR(" script filename ["+script->name+"] index ["<<script->index<<"]");
		int index_lower = script->index;
		int index_upper = script->index+1;
		oss.str("");
		oss<<index_lower;
		findAndReplace(line_copy,"%INDEX%",oss.str().c_str());
		oss.str("");
		oss<<index_upper;
		findAndReplace(line_copy,"%INDEX+1%",oss.str().c_str());
		script->fscript_writer<<line_copy;
		script->fscript_writer.flush();
		LOG_PAR(" Replaced to:["+line_copy+"]");
	}
}

void AmplScriptWriter::writeScript(ostringstream& oss)
{
	LOG_PAR("writeScript ["+oss.str()+"]");
	vector<AmplScript*>::iterator scripts_iter;
	for(scripts_iter = this->scriptList->begin();scripts_iter!=this->scriptList->end();scripts_iter++)
	{
		AmplScript *script = *scripts_iter;
		script->fscript_writer<<oss.str();
		script->fscript_writer.flush();
	}
}

//void AmplScriptWriter::writeScript(string line)
//{
//	LOG_PAR("writeScript ["+line+"]");
//	vector<AmplScript*>::iterator scripts_iter;
//	for(scripts_iter = this->scriptList->begin();scripts_iter!=this->scriptList->end();scripts_iter++)
//	{
//		AmplScript *script = *scripts_iter;
//		script->fscript_writer<<line<<endl;
//		script->fscript_writer.flush();
//	}
//}

void AmplScriptWriter::closeAll()
{
	LOG_PAR("close all script files - num of scripts["<<this->scriptList->size()<<"]");
	vector<AmplScript*>::iterator scripts_iter;
	for(scripts_iter=this->scriptList->begin();scripts_iter!=this->scriptList->end();scripts_iter++)
	{
		AmplScript *script = *scripts_iter;
		script->fscript_writer.close();
	}
}

AmplScriptWriter::~AmplScriptWriter() {
	LOG_PAR("AmplScriptWriter - destructor - num of scripts["<<this->scriptList->size()<<"]");
	vector<AmplScript*>::iterator scripts_iter;
	for(scripts_iter=this->scriptList->begin();scripts_iter!=this->scriptList->end();scripts_iter++)
	{
		AmplScript *script = *scripts_iter;
		delete script;
	}
	delete this->scriptList;
}
